#include <stdio.h>
#include <string.h>
#include "buf.h"
#include "parser.h"
#include "lexer.h"
#include "bson.h"

int bsonparse(yyscan_t, buf_t *, buf_t *);

int
bson_compile_bytes(char const *bytes, int length, buf_t *buf, buf_t *out, buf_t *err) {
  extra_t extra;
  yyscan_t scan;
  YY_BUFFER_STATE state;
  int result;
	
  extra.buf = buf;
  extra.err = err;
  extra.last_column = 0;
  memset(extra.hex_digits, 0, 5);
  bsonlex_init_extra(extra, &scan);
  state = bson_scan_bytes(bytes, length, scan);
  result = bsonparse(scan, out, err);
  bson_delete_buffer(state, scan);
  bsonlex_destroy(scan);
  return result;
}

int
bson_compile_string(char const *string, buf_t *buf, buf_t *out, buf_t *err) {
  extra_t extra;
  yyscan_t scan;
  YY_BUFFER_STATE state;
  int result;
	
  extra.buf = buf;
  extra.err = err;
  extra.last_column = 0;
  memset(extra.hex_digits, 0, 5);
  bsonlex_init_extra(extra, &scan);
  state = bson_scan_string(string, scan);
  result = bsonparse(scan, out, err);
  bson_delete_buffer(state, scan);
  bsonlex_destroy(scan);
  return result;
}

int
bson_compile_buffer(char *buffer, size_t size, buf_t *buf, buf_t *out, buf_t *err) {
  extra_t extra;
  yyscan_t scan;
  YY_BUFFER_STATE state;
  int result;
	
  extra.buf = buf;
  extra.err = err;
  extra.last_column = 0;
  memset(extra.hex_digits, 0, 5);
  bsonlex_init_extra(extra, &scan);
  if ((state = bson_scan_buffer(buffer, size, scan)) == NULL) {
    bsonlex_destroy(scan);
    buf_encode_literal(err, "yy_scan_buffer");
    return 1;
  }
  result = bsonparse(scan, out, err);
  bson_delete_buffer(state, scan);
  bsonlex_destroy(scan);
  return result;
}

int
bson_compile_stdin(buf_t *buf, buf_t *out, buf_t *err) {
  return bson_compile_file(stdin, buf, out, err);
}

int
bson_compile_file(FILE *file, buf_t *buf, buf_t *out, buf_t *err) {
  extra_t extra;
  yyscan_t scan;
  int result;
	
  extra.buf = buf;
  extra.err = err;
  extra.last_column = 0;
  memset(extra.hex_digits, 0, 5);
  bsonlex_init_extra(extra, &scan);
  bsonset_in(file, scan);
  result = bsonparse(scan, out, err);
  bsonlex_destroy(scan);
  return result;
}
